﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;

namespace Server
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        #region "Biến"
        CSocket socket;
        #endregion

        #region "Sự Kiện"
        /// <summary>
        /// Sự kiện load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Main_Load(object sender, EventArgs e)
        {
            this.Show();
            LangNgheKetNoi();
        }
        /// <summary>
        /// Sự kiện thread lắng nghe kết nối từ Client
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThreadLangNgheKetNoi_DoWork(object sender, DoWorkEventArgs e)
        {
            if (socket != null)
            {
                socket.ChapNhanKetNoiEvent += new CSocket.ChapNhanKetNoiHandler(socket_ChapNhanKetNoiEvent);
                socket.DongKetNoiEvent += new CSocket.DongKetNoiHandler(socket_DongKetNoiEvent);
                while (socket.IsConnect)
                {
                    TcpClient client = socket.ChapNhanKetNoi();
                }
            }
        }
        /// <summary>
        /// Đóng kết nối với Client
        /// </summary>
        /// <param name="count"></param>
        /// <param name="e"></param>
        void socket_DongKetNoiEvent(TcpClient client, int count, EventArgs e)
        {
            TreeNode node = CreateNode(client, false);
            treeNhatKy.Invoke((Action)(() => treeNhatKy.Nodes.Add(node)));
            statusStrip1.Invoke((Action)(() => lblSoNguoiTrucTuyen.Text = "Số Client: " + count.ToString()));
        }
        /// <summary>
        /// Sự kiện xảy ra khi có một Client kết nối tới
        /// </summary>
        /// <param name="count"></param>
        /// <param name="e"></param>
        void socket_ChapNhanKetNoiEvent(TcpClient client, int count, EventArgs e)
        {
            TreeNode node = CreateNode(client, true);

            treeNhatKy.Invoke((Action)(() => treeNhatKy.Nodes.Add(node)));
            statusStrip1.Invoke((Action)(() => lblSoNguoiTrucTuyen.Text = "Số Client: " + count.ToString()));


            BackgroundWorker threadnhandulieu = new BackgroundWorker();
            threadnhandulieu.DoWork += new DoWorkEventHandler(threadnhandulieu_DoWork);
            threadnhandulieu.RunWorkerAsync(client);
            ListViewItem item = new ListViewItem(new string[] { (listTrucTuyen.Items.Count + 1).ToString(), client.Client.RemoteEndPoint.ToString()});
            item.Tag = client.Client.RemoteEndPoint.ToString();
            listTrucTuyen.Invoke((Action)(() => listTrucTuyen.Items.Add(item)));
        }
        /// <summary>
        /// Tạo node open và close kết nối
        /// </summary>
        /// <param name="client"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private TreeNode CreateNode(TcpClient client, bool p)
        {
            string root = string.Empty;
            string[] arr = client.Client.RemoteEndPoint.ToString().Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
            if (p == true)//Log mớ kết nối
            {
                root = "Open connect: " + arr[0] + ":" + arr[1]
                    + ", Time: " + DateTime.Now;
            }
            else//Log đóng kết nối
            {
                root = "Close connect: " + arr[0] + ":" + arr[1]
                    + ", Time: " + DateTime.Now;
            }
            TreeNode node = new TreeNode(root);
            node.Nodes.Add("Ip: " + arr[0]);
            node.Nodes.Add("Port: " + arr[1]);

            CLog.GhiLog(root);
            return node;
        }
        /// <summary>
        /// Sự kiện bắt đầu quá trình nhận dự liệu từ 1 client
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void threadnhandulieu_DoWork(object sender, DoWorkEventArgs e)
        {
            CPhanTichGoiTin ptgt = new CPhanTichGoiTin();
            TcpClient client = (TcpClient)e.Argument;
            CGui_NhanDuLieu gui_nhan = new CGui_NhanDuLieu(client);
            gui_nhan.DongKetNoiEvent += new CGui_NhanDuLieu.DongKetNoiHandler(
                delegate {
                    socket.DongKetNoi(client);
                    return;
                }
                );
            bool flag = false;
            gui_nhan.GuiDuLieuEvent += new CGui_NhanDuLieu.GuiDuLieuHander(gui_nhan_GuiDuLieuEvent);
            gui_nhan.NhanDuLieuEvent += new CGui_NhanDuLieu.NhanDuLieuHandler(gui_nhan_NhanDuLieuEvent);
            while (client.Connected)
            {
                if (!client.Connected)
                {
                    client.Close();
                    return;
                }
                string str  = "";
                if (flag == false)
                {
                  str  = gui_nhan.NhanDuLieu(client);
                }
                if (!str.Equals(""))
                {
                    if(str.Equals("quit"))
                    {
                        flag = true;
                    }
                    //Phân tích yêu cầu từ phía Client
                    string msg_guidi = ptgt.PhanTichGoiTin(str);
                    //msg_guidi = msg_guidi.Trim();
                    //Gửi dữ liệu về cho client
                    if (!string.IsNullOrEmpty(msg_guidi))
                    {
                        BackgroundWorker threadguidulieu = new BackgroundWorker();
                        threadguidulieu.DoWork += new DoWorkEventHandler(
                            delegate
                            {
                                gui_nhan.GuiDuLieu(msg_guidi, client);
                                if (msg_guidi.Equals("quit"))
                                {
                                    socket.DongKetNoi(client);
                                }
                            }
                            );
                        threadguidulieu.RunWorkerAsync();
                    }
                }
            }
        }
        /// <summary>
        /// Event xảy ra khi nhận dữ liệu
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="client"></param>
        void gui_nhan_NhanDuLieuEvent(string msg, TcpClient client)
        {
            string[] arr = client.Client.RemoteEndPoint.ToString().Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
            TreeNode node = CreateNode(msg, client, false);

            treeNhatKy.Invoke((Action)(() => treeNhatKy.Nodes.Add(node)));
        }
        /// <summary>
        /// Event xảy ra khi gửi dữ liệu
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="client"></param>
        void gui_nhan_GuiDuLieuEvent(string msg, TcpClient client)
        {
            TreeNode node = CreateNode(msg, client, true);
            treeNhatKy.Invoke((Action)(() => treeNhatKy.Nodes.Add(node)));
        }
        /// <summary>
        /// Create node
        /// </summary>
        /// <param name="msg">Chuối log</param>
        /// <param name="client"></param>
        /// <param name="p">Flase: Nhận dữ liệu
        /// True: Gửi dữ liệu
        /// </param>
        /// <returns></returns>
        private TreeNode CreateNode(string msg, TcpClient client, bool p)
        {
            string[] arr = client.Client.RemoteEndPoint.ToString().Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
            string root = string.Empty;
            if (p == true)//Ghi log gửi dữ liệu
            {
                root = "Send: " + arr[0] + ":" + arr[1]
                    + ", Time: " + DateTime.Now
                    + ", " + "Leght: " + msg.Length
                    + ", Value: " + msg;
            }
            else//Ghi log nhận dữ liệu
            {
                root = "Receive: " + arr[0] + ":" + arr[1]
                   + ", Time: " + DateTime.Now
                   + ", " + "Leght: " + msg.Length
                   + ", Value: " + msg;
            }
            TreeNode node = new TreeNode(root);
            node.Nodes.Add("Ip: " + arr[0]);
            node.Nodes.Add("Port: " + arr[1]);
            node.Nodes.Add("Leght: " + msg.Length);
            node.Nodes.Add("Value: " + msg);

            CLog.GhiLog(root);

            return node;
        }
        /// <summary>
        /// Sự kiện cài đặt 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CaiDatCauHinh_Click(object sender, EventArgs e)
        {
            //Form cài đặt cấu hình
            Caidat frm = new Caidat();
            frm.ShowDialog();
        }
        /// <summary>
        /// Lắng nghe kết nối
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LangNgheKetNoi_Click(object sender, EventArgs e)
        {
            LangNgheKetNoi();
        }
        /// <summary>
        /// Lắng nghe kết nối
        /// </summary>
        private void LangNgheKetNoi()
        {
            try
            {
                BackgroundWorker ThreadLangNgheKetNoi = new BackgroundWorker();

                //Khởi tạo socket
                socket = new CSocket();
                ShowFormRestart("Khởi tạo kết nối ");
                btnLangNgheKetNoi.Enabled = false;

                ThreadLangNgheKetNoi.DoWork += new DoWorkEventHandler(ThreadLangNgheKetNoi_DoWork);
                ThreadLangNgheKetNoi.RunWorkerAsync();
            }
            catch (Exception c)
            {
                MessageBox.Show(c.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThoatChuongTrinh_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// Báo cáo Server
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BaoCao_Click(object sender, EventArgs e)
        {
            Baocao bc = new Baocao();
            bc.ShowDialog();
        }
        /// <summary>
        /// Quản lý sản phẩm
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DanhSachSanPham_Click(object sender, EventArgs e)
        {
            Danhsachsanpham frm = new Danhsachsanpham();
            frm.CapNhatSanPhamEvent += new Danhsachsanpham.CapNhatSanPhamHandler(frm_CapNhatSanPhamEvent);
            frm.ShowDialog();
        }

        /// <summary>
        /// Sự kiện cập nhật sản phẩm
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="e"></param>
        void frm_CapNhatSanPhamEvent(CProduct sp, EventArgs e)
        {
            string msg = "update|" + sp.Ma + "|" + sp.Ten + "|" + sp.Giatien + "|" + sp.Mota + "|" + sp.Ngaydang;
            BackgroundWorker threadGuiAll = new BackgroundWorker();
            threadGuiAll.DoWork += new DoWorkEventHandler(
                      delegate
                      {
                          for (int i = 0; i < socket.ListClient.Count; i++)
                          {
                              if (socket.ListClient[i].Connected)
                              {
                                  CGui_NhanDuLieu gui_nhan = new CGui_NhanDuLieu(socket.ListClient[i]);
                                  gui_nhan.GuiDuLieuEvent += new CGui_NhanDuLieu.GuiDuLieuHander(gui_nhan_GuiDuLieuEvent);
                                  gui_nhan.GuiDuLieu(msg, socket.ListClient[i]);
                              }
                          }
                      }
                      );
            threadGuiAll.RunWorkerAsync();
        }
        /// <summary>
        /// Nhất ký server
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NhatKy_Click(object sender, EventArgs e)
        {
            Nhatky frm = new Nhatky();
            frm.ShowDialog();
        }
        /// <summary>
        /// Ngắt kết nối
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NgatKetNoi_Click(object sender, EventArgs e)
        {
            if (socket != null)
            {
                for (int i = 0; i < socket.ListClient.Count; i++)
                {
                    if (socket.ListClient[i].Connected)
                    {
                        CGui_NhanDuLieu gui_nhan = new CGui_NhanDuLieu(socket.ListClient[i]);
                        gui_nhan.GuiDuLieuEvent += new CGui_NhanDuLieu.GuiDuLieuHander(gui_nhan_GuiDuLieuEvent);
                        gui_nhan.GuiDuLieu("quit", socket.ListClient[i]);
                    }
                }
                socket.DongKetNoi_All();
                btnLangNgheKetNoi.Enabled = true;
                btnLangNgheKetNoi.Tag = true;
                ShowFormRestart("Đóng kết nối ");
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        private void ShowFormRestart(string p)
        {
            Restart frm = new Restart();
            frm.Title = p;
            frm.ShowDialog();
        }
        /// <summary>
        /// Đóng form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(socket != null)
            {
                if (socket.IsConnect)
                {
                    NgatKetNoi_Click(sender, e);
                }
            }
        }
        #endregion

      
      
    }
}
